package ca.starfarer.kobold.model;

/**
 * @author Kevin
 */
public abstract class Creature extends DBObject {

    private String name;

    /**
     * The creature's maximum hit points. Cannot be zero or null.
     */
    private Integer maxHitPoints;

    /**
     * The creature's current hit points. Cannot be higher than its max hit points.
     */
    private Integer hitPoints;

    private Alignment alignment;

    public Creature() {
        // TODO
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getHitPoints() {
        return hitPoints;
    }

    /**
     * Sets the creature's current hit points. If you attempt to set more hit points than the creature's maximum hit
     * points, they will be adjusted downward.
     *
     * @param hitPoints
     */
    public void setHitPoints(Integer hitPoints) {
        this.hitPoints = hitPoints;
        fixHitPoints();
    }

    public Integer getMaxHitPoints() {
        return maxHitPoints;
    }

    /**
     * Sets the creature's maximum hit points.
     *
     * @param maxHitPoints
     *
     * @throws IllegalArgumentException if <tt>maxHitPoints</tt> is zero or negative
     */
    public void setMaxHitPoints(Integer maxHitPoints) {
        if (maxHitPoints != null && maxHitPoints <= 0) {
            throw new IllegalArgumentException("Max hit points must be > 0");
        }
        this.maxHitPoints = maxHitPoints;
        fixHitPoints();
    }

    /**
     * Ensures that the creature's current hit points are no more than its max hit points.
     */
    private void fixHitPoints() {
        if (maxHitPoints != null) {
            if (hitPoints != null && hitPoints > maxHitPoints) {
                hitPoints = maxHitPoints;
            }
        }
        else {
            hitPoints = null;
        }
    }

    public Integer getBloodiedValue() {
        if (maxHitPoints != null) {
            return maxHitPoints / 2;
        }
        else {
            return null;
        }
    }

    public void applyDamage(Damage damage) {
        if (hitPoints != null) {
            hitPoints -= damage.getValue();
        }
    }

    public Alignment getAlignment() {
        return alignment;
    }

    public void setAlignment(Alignment alignment) {
        this.alignment = alignment;
    }
}
